package org.eiahe.hr.performance.service.impl;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eiahe.hr.performance.domain.PerformancePositionIndicator;
import org.eiahe.hr.performance.domain.vo.PerformancePositionIndicatorVo;
import org.eiahe.hr.performance.service.IPerformancePositionIndicatorService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 岗位指标关联缓存服务
 * 用于优化频繁查询的性能
 *
 * @author zhangnn
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class PerformancePositionIndicatorCacheService {

    private final IPerformancePositionIndicatorService positionIndicatorService;

    // 缓存岗位指标权重
    private final ConcurrentHashMap<String, BigDecimal> weightCache = new ConcurrentHashMap<>();

    // 缓存岗位指标树状结构
    private final ConcurrentHashMap<Long, List<PerformancePositionIndicatorVo>> treeCache = new ConcurrentHashMap<>();

    // 缓存岗位直接关联指标
    private final ConcurrentHashMap<Long, List<PerformancePositionIndicator>> directIndicatorsCache = new ConcurrentHashMap<>();

    // 读写锁，保证线程安全
    private final ReadWriteLock weightCacheLock = new ReentrantReadWriteLock();
    private final ReadWriteLock treeCacheLock = new ReentrantReadWriteLock();
    private final ReadWriteLock directIndicatorsCacheLock = new ReentrantReadWriteLock();

    /**
     * 获取岗位指标权重（带缓存）
     * 
     * @param positionId  岗位ID
     * @param indicatorId 指标ID
     * @return 权重值
     */
    public BigDecimal getPositionIndicatorWeight(Long positionId, Long indicatorId) {
        if (positionId == null || indicatorId == null) {
            return BigDecimal.ZERO;
        }

        String cacheKey = positionId + ":" + indicatorId;

        // 先尝试从缓存获取
        weightCacheLock.readLock().lock();
        try {
            BigDecimal cachedWeight = weightCache.get(cacheKey);
            if (cachedWeight != null) {
                return cachedWeight;
            }
        } finally {
            weightCacheLock.readLock().unlock();
        }

        // 缓存未命中，从数据库查询
        BigDecimal weight = positionIndicatorService.getPositionIndicatorWeight(positionId, indicatorId);

        // 放入缓存
        weightCacheLock.writeLock().lock();
        try {
            weightCache.put(cacheKey, weight);
        } finally {
            weightCacheLock.writeLock().unlock();
        }

        return weight;
    }

    /**
     * 获取岗位指标树状结构（带缓存）
     * 
     * @param positionId 岗位ID
     * @return 指标树状结构
     */
    public List<PerformancePositionIndicatorVo> getPositionIndicatorTree(Long positionId) {
        if (positionId == null) {
            return null;
        }

        // 先尝试从缓存获取
        treeCacheLock.readLock().lock();
        try {
            List<PerformancePositionIndicatorVo> cachedTree = treeCache.get(positionId);
            if (cachedTree != null) {
                return cachedTree;
            }
        } finally {
            treeCacheLock.readLock().unlock();
        }

        // 缓存未命中，从数据库查询
        List<PerformancePositionIndicatorVo> tree = positionIndicatorService.getFullPositionIndicatorTree(positionId);

        // 放入缓存
        treeCacheLock.writeLock().lock();
        try {
            treeCache.put(positionId, tree);
        } finally {
            treeCacheLock.writeLock().unlock();
        }

        return tree;
    }

    /**
     * 获取岗位直接关联指标（带缓存）
     * 
     * @param positionId 岗位ID
     * @return 指标列表
     */
    public List<PerformancePositionIndicator> getDirectPositionIndicators(Long positionId) {
        if (positionId == null) {
            return null;
        }

        // 先尝试从缓存获取
        directIndicatorsCacheLock.readLock().lock();
        try {
            List<PerformancePositionIndicator> cachedIndicators = directIndicatorsCache.get(positionId);
            if (cachedIndicators != null) {
                return cachedIndicators;
            }
        } finally {
            directIndicatorsCacheLock.readLock().unlock();
        }

        // 缓存未命中，从数据库查询
        List<PerformancePositionIndicator> indicators = positionIndicatorService
                .getDirectPositionIndicators(positionId);

        // 放入缓存
        directIndicatorsCacheLock.writeLock().lock();
        try {
            directIndicatorsCache.put(positionId, indicators);
        } finally {
            directIndicatorsCacheLock.writeLock().unlock();
        }

        return indicators;
    }

    /**
     * 清除指定岗位的缓存
     * 
     * @param positionId 岗位ID
     */
    public void clearPositionCache(Long positionId) {
        if (positionId == null) {
            return;
        }

        // 清除权重缓存中该岗位相关的条目
        weightCacheLock.writeLock().lock();
        try {
            weightCache.entrySet().removeIf(entry -> entry.getKey().startsWith(positionId + ":"));
        } finally {
            weightCacheLock.writeLock().unlock();
        }

        // 清除树状结构缓存
        treeCacheLock.writeLock().lock();
        try {
            treeCache.remove(positionId);
        } finally {
            treeCacheLock.writeLock().unlock();
        }

        // 清除直接关联指标缓存
        directIndicatorsCacheLock.writeLock().lock();
        try {
            directIndicatorsCache.remove(positionId);
        } finally {
            directIndicatorsCacheLock.writeLock().unlock();
        }
    }

    /**
     * 清除所有缓存
     */
    public void clearAllCache() {
        weightCacheLock.writeLock().lock();
        try {
            weightCache.clear();
        } finally {
            weightCacheLock.writeLock().unlock();
        }

        treeCacheLock.writeLock().lock();
        try {
            treeCache.clear();
        } finally {
            treeCacheLock.writeLock().unlock();
        }

        directIndicatorsCacheLock.writeLock().lock();
        try {
            directIndicatorsCache.clear();
        } finally {
            directIndicatorsCacheLock.writeLock().unlock();
        }
    }
}